/*
 * sc_noti_log.h
 *
 *  Created on: Aug 22, 2010
 *      Author: sdaniele
 */

#ifndef SC_NOTI_LOG_H_
#define SC_NOTI_LOG_H_



namespace sc_core {

// ----------------------------------------------------------------------------
//  CLASS : sc_noti_log
//
//  Class for storing notification state in thread-local storage
// ----------------------------------------------------------------------------

class sc_noti_log
{

public:	/*internal to sc_simcontext*/
	sc_noti_log()
		: m_pending_type(NONE)
		, m_has_immediate(false)
	{}

	void immediate(){
		//dbg_println("sc_noti_log::immediate() has been invoked with l=",this);
		m_pending_type = NONE;
		m_has_immediate = true;
	}

	void delta(){
		//dbg_println("sc_noti_log::delta() has been invoked with l=",this);
		m_pending_type = DELTA;
	}

	void timed(const sc_time& t){
		//dbg_println("sc_noti_log::timed() has been invoked with l=",this);
		if(m_pending_type == DELTA){
			//dbg_println("		taken `if(m_pending_type == DELTA)` path with\n\t\t l=",this);
			return;
		}
		if(m_pending_type == TIMED && t < m_notify_time){
			//dbg_println("		taken `if(m_pending_type == TIMED && t < m_notify_time)` path with\n\t\t l=",this);
			m_notify_time = t;
			return;
		}
		if(m_pending_type == NONE){
			//dbg_println("     	taken `if(m_pending_type == NONE)` path with\n\t\t l=",this);
			m_pending_type = TIMED;
			m_notify_time = t;
		}
	}

	void cancel(){
		//dbg_println("sc_noti_log::cancel() has been invoked with l=",this);
		m_pending_type = NONE;
	}

	bool has_immediate() const {
		return m_has_immediate;
	}
	void reset_immediate(){
		m_has_immediate = false;
	}

	bool has_delta() const {
		return m_pending_type == DELTA;
	}

	void reset_delta(){
		assert(m_pending_type == DELTA);
		m_pending_type = NONE;
	}

	bool has_timed() const {
		return m_pending_type == TIMED;
	}

	const sc_time& time() const {
		assert(m_pending_type == TIMED);
		return m_notify_time;
	}

	void reset_timed(){
		assert(m_pending_type == TIMED);
		m_pending_type = NONE;
	}


private:
	enum notify_t { NONE, DELTA, TIMED };		/*code duplication from sc_event class*/
	notify_t		m_pending_type;				//type of pending notification
	sc_time 		m_notify_time;				//time (for timed notifications only)
	bool			m_has_immediate;			//requested immediate notifications count
};

}

#endif /* SC_NOTI_LOG_H_ */
